package com.fintech.pangu.autoconfigure.security;

import com.fintech.pangu.autoconfigure.security.oauth2.client.OAuth2SsoClientSecurityAutoConfiguration;
import com.fintech.pangu.autoconfigure.security.properties.PanGuSecurityProperties;
import com.fintech.pangu.security.authentication.model.SecurityUser;
import com.fintech.pangu.security.authorize.AuthorizeConfigManager;
import com.fintech.pangu.security.config.PanGuAuthenticationManagerBuilderManager;
import com.fintech.pangu.security.config.PanGuHttpSecurityManager;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;

import java.util.List;

/**
 * 默认的PanGuWebSecurityAutoConfiguration，在没有其它任何实现类时启用
 */
@Configuration
@EnableConfigurationProperties(PanGuSecurityProperties.class)
@AutoConfigureAfter({OAuth2SsoClientSecurityAutoConfiguration.class})  // 晚于其它PanGuWebSecurityAutoConfiguration实现类
@ConditionalOnMissingBean(PanGuWebSecurityConfigurationAdapter.class) // 仍没有PanGuWebSecurityAutoConfiguration实现类
@Order(1000)
public class DefaultPanGuWebSecurityAutoConfiguration extends PanGuWebSecurityConfigurationAdapter {

    @Autowired
    private PanGuSecurityProperties panGuSecurityProperties;

    public DefaultPanGuWebSecurityAutoConfiguration(
            PanGuSecurityProperties panGuSecurityProperties,
            PasswordEncoder passwordEncoder,
            ObjectProvider<PanGuHttpSecurityManager> panGuHttpSecurityManager,
            ObjectProvider<AuthorizeConfigManager> authorizeConfigManager,
            ObjectProvider<PanGuAuthenticationManagerBuilderManager> panGuAuthenticationManagerBuilderManager){
        super(panGuSecurityProperties, passwordEncoder, panGuHttpSecurityManager.getIfAvailable(), authorizeConfigManager.getIfAvailable(), panGuAuthenticationManagerBuilderManager.getIfAvailable());
    }

    @Override
    protected void customAuthenticationManagerBuilder(AuthenticationManagerBuilder auth) throws Exception {
        // 是否开启默认用户，默认开启
        if(panGuSecurityProperties.getAuthentication().isDefaultUsersEnable()){
            auth
                .userDetailsService(userDetailsService()) // 配置文件中用户 或 默认admin
                .passwordEncoder(getPasswordEncoder());
        }
    }


    /**
     * 默认的UserDetailsService
     * 从配置文件加载用户信息到内存
     * @return
     */
    @Override
    @Bean
    protected UserDetailsService userDetailsService() {
        InMemoryUserDetailsManager memoryUserDetails = new InMemoryUserDetailsManager();

        // 配置文件中用户
        List<SecurityUser> users = panGuSecurityProperties.getAuthentication().getUsers();
        if (!ObjectUtils.isEmpty(users)) {
            for (SecurityUser securityUser : users) {
                Assert.hasText(securityUser.getUsername(), "配置文件中登录用户username不能为空");
                Assert.hasText(securityUser.getPassword(), "配置文件中登录用户password不能为空");

                memoryUserDetails.createUser(
                        User.builder()
                                .username(securityUser.getUsername().trim())
                                .password(getPasswordEncoder().encode(securityUser.getPassword().trim()))
                                .roles(securityUser.getRoles())
                                .build()
                );
            }
        }

        // 如果没有配置，添加默认用户
        if (ObjectUtils.isEmpty(users)) {
            memoryUserDetails.createUser(
                    User.builder()
                            .username("admin")
                            .password(getPasswordEncoder().encode("admin"))
                            .roles("ADMIN")
                            .build()
            );
        }

        return memoryUserDetails;
    }


}
